package com.aliyun.heiyu.powermaster.server.service;


import com.aliyun.heiyu.common.source.ConnectionManager;
import com.aliyun.heiyu.common.util.*;
import com.aliyun.heiyu.common.util.SM4Util;
import com.aliyun.heiyu.powermaster.proto.*;
import com.aliyun.heiyu.powermaster.server.Error;
import com.aliyun.heiyu.powermaster.server.dao.LogHistoryDao;
import com.aliyun.heiyu.powermaster.server.dao.entity.LogHistoryEntity;
import com.aliyun.heiyu.powermaster.server.dao.enums.LogConfigEnum;
import com.aliyun.heiyu.powermaster.server.dao.enums.LogLevelEnum;
import com.aliyun.heiyu.powermaster.server.dao.impl.LogHistoryImpl;
import com.google.gson.internal.bind.util.ISO8601Utils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.concurrent.BasicThreadFactory;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;

import java.io.FileWriter;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class PropertiesServiceImpl implements PropertiesService {

    private static volatile PropertiesServiceImpl instance;
    /*log4j2.xml 运行时文件路径**/
    private static final String FILEPATH = getRunPath() + "/log4j2.xml";

    private static Logger logger = LoggerFactory.getLogger(PropertiesServiceImpl.class);

    private LogHistoryDao logHistoryDao;

    //数据库备份时间
    private static int time;
    //项目所用配置
    private static int status;

    private static ScheduledExecutorService service = new ScheduledThreadPoolExecutor(1, new BasicThreadFactory.Builder().namingPattern("save-database-backup-pool-%d").daemon(true).build());


    public static PropertiesServiceImpl getInstance() {
        synchronized (PropertiesServiceImpl.class) {
            if (instance == null) {
                instance = new PropertiesServiceImpl();
            }
            return instance;
        }
    }

    private PropertiesServiceImpl() {

        this.logHistoryDao = new LogHistoryImpl();
        //数据库备份定时任务
        try {
            databaseBackupTask(true);
        } catch (InterruptedException e) {

        }
    }

    public void databaseBackupTask(Boolean status) throws InterruptedException {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                logger.info("执行数据库备份的任务+++{}", System.currentTimeMillis());
                databaseBackupThread();
                logger.info("执行数据库备份的任务完成+++{}", System.currentTimeMillis());
            }
        };
        int period = time == 0 ? 3 : time;
        if (status) {
            service.shutdown();
            Thread.sleep(500);
            service = new ScheduledThreadPoolExecutor(1, new BasicThreadFactory.Builder().namingPattern("save-database-backup-pool-%d").daemon(true).build());
            service.scheduleAtFixedRate(runnable, 0, period, TimeUnit.DAYS);
        } else {
            service.scheduleAtFixedRate(runnable, 0, period, TimeUnit.DAYS);
        }
    }

    @Override
    public String databaseBackup() {
        databaseBackupThread();
        return "数据库备份文件已生成";
    }

    /**
     * 定时备份数据库
     */
    public void databaseBackupThread() {
        Properties dbProps = ConnectionManager.getDBProps();
        if(dbProps == null){
            dbProps = ConnectionManager.check();
        }
        String a = dbProps.getProperty("master.jdbc.user");
        String b = dbProps.getProperty("master.jdbc.password");
        String serverIp = PropertiesUtil.getValue("logConfig.properties", "sgrdbServerIp");
        int serverPort = Integer.valueOf(PropertiesUtil.getValue("logConfig.properties", "sgrdbServerPort"));
        int dbPort = Integer.valueOf(PropertiesUtil.getValue("logConfig.properties", "sgrdbDBPort"));
        String sshuser = PropertiesUtil.getValue("logConfig.properties","sgrdbServerName");
        String sshp = PropertiesUtil.getValue("logConfig.properties","sgrdbServerPwd");
        String commond1 = PropertiesUtil.getValue("logConfig.properties","sgrdbBackShell1");
        String commond2 = PropertiesUtil.getValue("logConfig.properties","sgrdbBackShell2");
        if(a != null){
            a = SM4Util.decrypt_CBC(a);
        } else {
            a = "";
        }
        if(b != null){
            b = SM4Util.decrypt_CBC(b);
        } else {
            b = "";
        }
        if(sshuser != null){
            sshuser = SM4Util.decrypt_CBC(sshuser);
        } else {
            sshuser = "";
        }
        if(sshp != null){
            sshp = SM4Util.decrypt_CBC(sshp);
        } else {
            sshp = "";
        }
        StringBuffer buffer = new StringBuffer();
        buffer.append(commond1)
            .append(" -u").append(a)
            .append(" -p").append(b)
            .append(" -h").append(serverIp)
            .append(" -P").append(dbPort)
            .append(" ").append(commond2);

        SSHUtil util = new SSHUtil(serverIp, serverPort, sshuser,sshp);

        //数据库备份语句
        String command = buffer.toString();
        util.exeCommand(command);
        a = null;
        b = null;
        sshuser = null;
        sshp = null;
    }

    @Override
    public void databaseBackupTime(DatabaseBackupTimeRequest request) {
        try {
            if (request.getTime() != 0) {
                time = request.getTime();
                databaseBackupTask(true);
            }
        } catch (InterruptedException e) {
            return;
        }
    }

    @Override
    public int getDatabaseBackupTime() {
        return time == 0 ? 3 : time;
    }

    @Override
    public GetDatabaseBackupTimeReply getDatabaseBackupData() {
        int i = time == 0 ? 3 : time;
        GetDatabaseBackupTimeReply.Builder builder = GetDatabaseBackupTimeReply.newBuilder();
        builder.setTime(i).setErrCode(Error.SUCCESS.getCode()).setErrMsg(Error.SUCCESS.getMessage());
        Properties dbProps = ConnectionManager.getDBProps();
        if(dbProps == null){
            dbProps = ConnectionManager.check();
        }
        String a = dbProps.getProperty("master.jdbc.user");
        String b =  dbProps.getProperty("privileges.database");
        if(a != null){
            a = SM4Util.decrypt_CBC(a);
        } else {
            a = "";
        }
        if(b != null){
            b = SM4Util.decrypt_CBC(b);
        } else {
            b = "";
        }
        builder.setName(a).setBackUpPrivileges(b);
        return builder.build();
    }

    @Override
    public void updateLogEnvironment(UpdateLogEnvironmentRequest request) {
        UpdateLogRequest.Builder builder = UpdateLogRequest.newBuilder();

        if ("dev".equals(request.getEnvironment())) {
            builder = conversionUpdateLogRequest(LogConfigEnum.DEV_LOG_CONFIG.getRootLevel(),
                LogConfigEnum.DEV_LOG_CONFIG.getLevelName(),
                LogConfigEnum.DEV_LOG_CONFIG.getLogSize(),
                LogConfigEnum.DEV_LOG_CONFIG.getLogSum(),
                LogConfigEnum.DEV_LOG_CONFIG.getLogMonitorInterval());
            status = 1;
        } else if ("test".equals(request.getEnvironment())) {
            builder = conversionUpdateLogRequest(LogConfigEnum.TEST_LOG_CONFIG.getRootLevel(),
                LogConfigEnum.TEST_LOG_CONFIG.getLevelName(),
                LogConfigEnum.TEST_LOG_CONFIG.getLogSize(),
                LogConfigEnum.TEST_LOG_CONFIG.getLogSum(),
                LogConfigEnum.TEST_LOG_CONFIG.getLogMonitorInterval());
            status = 2;
        } else if ("pro".equals(request.getEnvironment())) {
            builder = conversionUpdateLogRequest(LogConfigEnum.PRO_LOG_CONFIG.getRootLevel(),
                LogConfigEnum.PRO_LOG_CONFIG.getLevelName(),
                LogConfigEnum.PRO_LOG_CONFIG.getLogSize(),
                LogConfigEnum.PRO_LOG_CONFIG.getLogSum(),
                LogConfigEnum.PRO_LOG_CONFIG.getLogMonitorInterval());
            status = 3;
        }
        updateLogConfig1(builder.build());
    }

    @Override
    public int getLogEnvironment() {
        return status;
    }


    @Override
    public void updateLogConfig(UpdateLogRequest request) {
        status = 0;
        updateLogConfig1(request);
    }

    private void updateLogConfig1(UpdateLogRequest request) {
        try {
            LogHistoryEntity entity = new LogHistoryEntity();
            String path = CleanPathUtil.cleanString(FILEPATH);
            File file = new File(CleanPathUtil.cleanString(FILEPATH));
            if (ObjectUtils.isEmpty(file)) {
                throw new RuntimeException("未读取到日志文件");
            }
            SAXReader reader = new SAXReader();
            Document document = reader.read(file);

            //更改root日志级别
            if (!StringUtil.isEmpty(request.getRootLevel())) {
                Boolean flag = checkLogLevel(request.getRootLevel());
                if (!flag) {
                    throw new RuntimeException("日志级别输入错误");
                }
                Element element = (Element) document.selectNodes("/Configuration/Loggers/Root").get(0);
                element.addAttribute("level", request.getRootLevel());
                entity.setRoot_level(request.getRootLevel());
            }

            //更改普通日志级别
            if (!StringUtil.isEmpty(request.getLevelName())) {
                Boolean flag = checkLogLevel(request.getLevelName());
                if (!flag) {
                    throw new RuntimeException("日志级别输入错误");
                }
                List list = document.selectNodes("/Configuration/Loggers/Logger");
                if (list.size() > 0) {
                    for (Iterator it = list.iterator(); it.hasNext(); ) {
                        Element elm = (Element) it.next();
                        elm.addAttribute("level", request.getLevelName());
                    }
                    entity.setLevel(request.getLevelName());
                }
            }

            //更改日志文件存储大小
            if (request.getLogSize() > 0 && request.getLogSize() <= 1024) {
                List<Element> list = document.selectNodes("/Configuration/Appenders/RollingRandomAccessFile/Policies/SizeBasedTriggeringPolicy");
                if (list.size() > 0) {
                    for (Iterator it = list.iterator(); it.hasNext(); ) {
                        Element elm = (Element) it.next();
                        elm.addAttribute("size", request.getLogSize() + "MB");
                    }
                    entity.setLog_size(request.getLogSize());
                }
            }

            //更改日志文件存储个数
            if (request.getLogSum() > 0 && request.getLogSum() <= 20) {
                List<Element> list = document.selectNodes("/Configuration/Appenders/RollingRandomAccessFile/DefaultRolloverStrategy");
                if (list.size() > 0) {
                    for (Iterator it = list.iterator(); it.hasNext(); ) {
                        Element elm = (Element) it.next();
                        elm.addAttribute("max", request.getLogSum() + "");
                    }
                    entity.setLog_num(request.getLogSum());
                }
            }

            //更改日志的热加载时间
            if (request.getMonitorInterval() > 0) {
                Element element = (Element) document.selectNodes("/Configuration").get(0);
                //修改节点的属性
                element.addAttribute("monitorInterval", request.getMonitorInterval() + "");
                entity.setMonitorInterval(request.getMonitorInterval());
            }

            writeLog4j(document, FILEPATH);

            entity.setLog_switch(request.getLogStatus());
            //添加进入数据库
            Integer result = logHistoryDao.saveLogHistory(entity);
        } catch (DocumentException e) {
            e.printStackTrace();
        }
    }

    @Override
    public UpdateLogRequest getLogConfig() {
        try {
            String path = CleanPathUtil.cleanString(FILEPATH);
            File file = new File(CleanPathUtil.cleanString(FILEPATH));
            if (ObjectUtils.isEmpty(file)) {
                throw new RuntimeException("未读取到日志文件");
            }
            Document document = SAXReaderUtil.getDocument(file);

            UpdateLogRequest.Builder builder1 = UpdateLogRequest.newBuilder();

            //根目录级别
            Element element = (Element) document.selectNodes("/Configuration/Loggers/Root").get(0);
            builder1.setRootLevel(element.attributeValue("level"));


            //普通日志级别
            Element element1 = (Element) document.selectNodes("/Configuration/Loggers/Logger").get(0);
            builder1.setLevelName(element1.attributeValue("level"));


            //日志文件存储大小
            Element element2 = (Element) document.selectNodes("/Configuration/Appenders/RollingRandomAccessFile/Policies/SizeBasedTriggeringPolicy").get(0);
            String param = element2.attributeValue("size").substring(0, element2.attributeValue("size").length() - 2);
            builder1.setLogSize(Integer.valueOf(param));


            //日志文件存储个数
            Element element3 = (Element) document.selectNodes("/Configuration/Appenders/RollingRandomAccessFile/DefaultRolloverStrategy").get(0);
            builder1.setLogSum(Integer.valueOf(element3.attributeValue("max")));


            //更改日志的热加载时间
            Element element4 = (Element) document.selectNodes("/Configuration").get(0);
            //修改节点的属性
            builder1.setMonitorInterval(Integer.valueOf(element4.attributeValue("monitorInterval")));

            //查询最新一条日志的开关状态
            LogHistoryEntity entity = logHistoryDao.selectLast();
            if(ObjectUtils.isEmpty(entity)){
                builder1.setLogStatus(0);
            }else{
                builder1.setLogStatus(entity.getLog_switch());
            }
            return builder1.build();
        } catch (Exception e) {
            return null;
        }
    }


    @Override
    public List<LogMassage> findLogByCondition(GetLogMassageRequest request) {
        Date endTimeSwitch = new Date();
        LogHistoryEntity entity = logHistoryDao.selectLast();
        if (entity.getLog_switch() == 1) {
            endTimeSwitch = entity.getCreate_time();
        }
        Date levelEndTime = entity.getCreate_time();
        String loglevel = entity.getLevel();

        String logName = request.getLogName();
        SimpleDateFormat sim = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        int i = 1;

        //判断logname得到log的地址
        String address = "";
        if ("power-thunder.log".equals(logName)) {

            String startTime = request.getStartTime().substring(0, 14) + "[0-9][0-9]";
            String endTime = request.getEndTime();

            String thunderLogPath = PropertiesUtil.getValue("logConfig.properties", "thunderLogPath");

            address = thunderLogPath + logName;

            String serverIp = PropertiesUtil.getValue("logConfig.properties", "thunderServerIp");
            int serverPort = Integer.valueOf(PropertiesUtil.getValue("logConfig.properties", "thunderServerPort"));
            String serverName = PropertiesUtil.getValue("logConfig.properties", "thunderServerName");
            String serverP = PropertiesUtil.getValue("logConfig.properties", "thunderServerPwd");

            //获取链接
            SSHUtil util = new SSHUtil(serverIp, serverPort, serverName, serverP);
            //组装命令
            StringBuffer cmd = new StringBuffer("sed -n '/" + startTime + "/,/" + endTime + "/p' " + address);
            StringBuffer cmdBack = new StringBuffer("tail -n 10000 " + address);
            if (!StringUtil.isEmpty(request.getKeyWord())) {
                cmd.append(" |grep -i ").append(request.getKeyWord());
                cmdBack.append(" |grep -i ").append(request.getKeyWord());
            }
            if (!StringUtil.isEmpty(request.getLevelName())) {
                cmd.append(" |grep ").append(request.getLevelName());
                cmdBack.append(" |grep ").append(request.getLevelName());
            }
            //执行命令
            List<String> list = util.exeCommand1(cmd.toString());
            if (ObjectUtils.isEmpty(list)) {
                list = util.exeCommand1(cmdBack.toString());
            }
            if (ObjectUtils.isEmpty(list)) {
                return null;
            }
            List<LogMassage> resultList = new ArrayList<>(list.size());
            for (String logInfo : list) {
                LogMassage.Builder builder = LogMassage.newBuilder();
                Date parse = new Date();
                try {
                    String date = logInfo.substring(0, 19);
                    parse = sim.parse(date);
                } catch (Exception e) {
                    if (!ObjectUtils.isEmpty(resultList)) {
                        LogMassage logMassage = resultList.get(resultList.size() - 1);
                        LogMassage.Builder builder1 = LogMassage.newBuilder().setMessage(logMassage.getMessage() + "\n" + logInfo).setDate(logMassage.getDate()).setLevel(logMassage.getLevel());
                        resultList.set(resultList.size() - 1, builder1.build());
                    }
                    continue;
                }
                if (parse.getTime() < TimeConvertUtil.dateToMillisecond(request.getStartTime() + ":00")) {
                    continue;
                }
                if (parse.getTime() > TimeConvertUtil.dateToMillisecond(request.getEndTime() + ":00") || parse.getTime() > endTimeSwitch.getTime()) {
                    break;
                }
                String level = logInfo.substring(20, 25).replace(" ", "");
                if (!StringUtil.isEmpty(request.getLevelName())) {
                    if (!level.equals(request.getLevelName())) {
                        continue;
                    }
                }
                if(parse.getTime() > levelEndTime.getTime()) {
                    if (loglevel.equals("info") && level.equals("DEBUG")) {
                        continue;
                    }
                    if (loglevel.equals("warn") && (level.equals("DEBUG") || level.equals("INFO"))) {
                        continue;
                    }
                    if (loglevel.equals("error") && (level.equals("DEBUG") || level.equals("INFO") || level.equals("WARN"))) {
                        continue;
                    }
                }
                String message = logInfo.substring(25, logInfo.length());
                builder.setId(i);
                builder.setDate(TimeConvertUtil.getStringDate(parse));
                builder.setLevel(level);
                builder.setMessage(message);
                resultList.add(builder.build());
                i++;
            }
            Collections.reverse(resultList);
            return resultList;

        } else if ("metrics.log".equals(logName) || "signInMetrics.log".equals(logName)) {
            if("signInMetrics.log".equals(logName)){
                logName = "iscMetrics.log";
            }

            String startTime = request.getStartTime().replace(" ", "T").substring(0, 14) + "[0-9][0-9]";
            String endTime = request.getEndTime().replace(" ", "T");

            if(logName .equals("iscMetrics.log")){
                startTime = startTime.replace("T", " ");
                endTime = request.getEndTime().replace("T", " ");
            }
            String serverName = PropertiesUtil.getValue("logConfig.properties", "userName");
            String serverP = PropertiesUtil.getValue("logConfig.properties", "password");
            int port = Integer.valueOf(PropertiesUtil.getValue("logConfig.properties", "port"));
            //获取链接
            SSHUtil util = new SSHUtil("localhost", port, serverName, serverP);
            String runPath = getRunPath();
            address = runPath.substring(0, runPath.length() - 4) + "bin/" + logName;
            //组装命令
            StringBuffer cmd = new StringBuffer("sed -n '/" + startTime + "/,/" + endTime + "/p' " + address);
            StringBuffer cmdBack = new StringBuffer("tail -n 10000 " + address);
            if (!StringUtil.isEmpty(request.getKeyWord())) {
                cmd.append(" |grep -i ").append(request.getKeyWord());
                cmdBack.append(" |grep -i ").append(request.getKeyWord());
            }
            if (!StringUtil.isEmpty(request.getLevelName())) {
                cmd.append(" |grep ").append(request.getLevelName());
                cmdBack.append(" |grep ").append(request.getLevelName());
            }
            //执行命令
            List<String> list = util.exeCommand1(cmd.toString());
            if (ObjectUtils.isEmpty(list)) {
                list = util.exeCommand1(cmdBack.toString());
            }
            if (ObjectUtils.isEmpty(list)) {
                return null;
            }
            List<LogMassage> resultList = new ArrayList<>(list.size());
            for (String logInfo : list) {
                LogMassage.Builder builder = LogMassage.newBuilder();
                Date parse = new Date();
                try {
                    String dateInfo = logInfo.substring(0, 23).replace(",", ".");
                    if(logName .equals("iscMetrics.log")){
                        dateInfo = dateInfo.replace(" ", "T");
                    }
                    String date = dateInfo + "+08:00";
                    parse = ISO8601Utils.parse(date, new ParsePosition(0));
                } catch (Exception e) {
                    if (!ObjectUtils.isEmpty(resultList)) {
                        LogMassage logMassage = resultList.get(resultList.size() - 1);
                        LogMassage.Builder builder1 = LogMassage.newBuilder().setMessage(logMassage.getMessage() + "\n" + logInfo).setDate(logMassage.getDate()).setLevel(logMassage.getLevel());
                        resultList.set(resultList.size() - 1, builder1.build());
                    }
                    continue;
                }
                if (parse.getTime() < TimeConvertUtil.dateToMillisecond(request.getStartTime() + ":00")) {
                    continue;
                }
                if (parse.getTime() > TimeConvertUtil.dateToMillisecond(request.getEndTime() + ":00") || parse.getTime() > endTimeSwitch.getTime()) {
                    break;
                }

                String level = logInfo.substring(24, 29).replace(" ", "");
                if (!StringUtil.isEmpty(request.getLevelName())) {
                    if (!level.equals(request.getLevelName())) {
                        continue;
                    }
                }
                
                if(parse.getTime() > levelEndTime.getTime()) {
                    if (loglevel.equals("info") && level.equals("DEBUG")) {
                        continue;
                    }
                    if (loglevel.equals("warn") && (level.equals("DEBUG") || level.equals("INFO"))) {
                        continue;
                    }
                    if (loglevel.equals("error") && (level.equals("DEBUG") || level.equals("INFO") || level.equals("WARN"))) {
                        continue;
                    }
                }
                String message = logInfo.substring(29, logInfo.length());
                builder.setId(i);
                builder.setDate(TimeConvertUtil.getStringDate(parse));
                builder.setLevel(level);
                builder.setMessage(message);
                resultList.add(builder.build());
                i++;
            }
            Collections.reverse(resultList);
            return resultList;
        }
        return null;
    }

    @Override
    public List<UpdateLogRequest> getLogHistory(GetLogHistoryRequest request) {
        List<LogHistoryEntity> entityList = logHistoryDao.getLogHistory(request);

        if (ObjectUtils.isEmpty(entityList)) {
            return null;
        }
        List<UpdateLogRequest> result = new ArrayList<>(entityList.size());
        for (LogHistoryEntity entity : entityList) {
            UpdateLogRequest.Builder builder = UpdateLogRequest.newBuilder();
            builder.setId(entity.getId());
            builder.setRootLevel(entity.getRoot_level());
            builder.setLevelName(entity.getLevel());
            builder.setLogSum(entity.getLog_num());
            builder.setLogSize(entity.getLog_size());
            builder.setMonitorInterval(entity.getMonitorInterval());
            builder.setCreateTime(TimeConvertUtil.getStringDate(entity.getCreate_time()));
            result.add(builder.build());
        }
        return result;
    }


    private UpdateLogRequest.Builder conversionUpdateLogRequest(String rootLevel, String levelName, int logSize, int logSum, int logMonitorInterval) {
        UpdateLogRequest.Builder builder = UpdateLogRequest.newBuilder();
        builder.setRootLevel(rootLevel);
        builder.setLevelName(levelName);
        builder.setLogSize(logSize);
        builder.setLogSum(logSum);
        builder.setMonitorInterval(logMonitorInterval);
        builder.setLogStatus(0);
        return builder;
    }



    private Boolean checkLogLevel(String levelName) {
        List<String> list = new ArrayList<>();
        for (LogLevelEnum logLevelEnum : LogLevelEnum.values()) {
            list.add(logLevelEnum.getDesc());
        }
        if (!list.contains(levelName)) {
            return false;
        }
        return true;
    }

    private static void writeLog4j(Document document, String filePath) {
        XMLWriter writer = null;
        FileWriter fileWriter = null;
        try {
            OutputFormat format = OutputFormat.createPrettyPrint();//有缩进的格式化输出
            format.setEncoding("UTF-8");//指定XML编码
            //1、创建XMLWriter对象，指定写出的文件路径
            String path = CleanPathUtil.cleanString(filePath);
            fileWriter = new FileWriter(new File(CleanPathUtil.cleanString(filePath)));
            writer = new XMLWriter(fileWriter, format);
            //2、调用writer方法将内存内容写出
            writer.write(document);
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(fileWriter != null){
                safeClose(fileWriter);
            }
            if(writer != null){
                safeClose(writer);
            }
        }
    }

    public static void safeClose(XMLWriter fis) {
        if (fis != null) {
            try {
                fis.close();
            } catch (IOException e) {
                logger.error(e.getMessage());
            }
        }
    }
    public static void safeClose(FileWriter fis) {
        if (fis != null) {
            try {
                fis.close();
            } catch (IOException e) {
                logger.error(e.getMessage());
            }
        }
    }

    public static String getRunPath() {
        /**
         * 方法一：获取当前可执行jar包所在目录
         */
        String filePath = PropertiesUtil.getFilePath();
        if (filePath.contains("..\\")) {
            filePath = filePath.replace("..\\", "");
        }
        if (filePath.contains("../")) {
            filePath = filePath.replace("../", "");
        }
        if (filePath.contains("./")) {
            filePath = filePath.replace("./", "");
        }
        String pathSplit = PropertiesUtil.getPathSplit();//得到当前操作系统的分隔符，windows下是";",linux下是":"
        if (pathSplit.contains("..\\")) {
            pathSplit = pathSplit.replace("..\\", "");
        }
        if (pathSplit.contains("../")) {
            pathSplit = pathSplit.replace("../", "");
        }
        if (pathSplit.contains("./")) {
            pathSplit = pathSplit.replace("./", "");
        }
        /**
         * 若没有其他依赖，则filePath的结果应当是该可运行jar包的绝对路径，
         * 此时我们只需要经过字符串解析，便可得到jar所在目录
         */
        if (filePath.contains(pathSplit)) {
            filePath = filePath.substring(0, filePath.indexOf(pathSplit));
        } else if (filePath.endsWith(".jar")) {//截取路径中的jar包名,可执行jar包运行的结果里包含".jar"
            filePath = filePath.substring(0, filePath.lastIndexOf(File.separator) + 1);
        }
        return filePath;
    }
}
